package com.link2room.soundwave.facade.impl;

import com.link2room.common.constant.DefaultValue;
import com.link2room.common.dto.param.base.BaseL2rParamDto;
import com.link2room.common.entity.BaseEntity;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.*;
import com.link2room.enums.exception.SoundwaveSysExceptionEnum;
import com.link2room.soundwave.entity.L2RYhHotel;
import com.link2room.soundwave.entity.L2RYhRmtype;
import com.link2room.soundwave.entity.YhRmtypeAvailSync;
import com.link2room.soundwave.exception.SoundwaveException;
import com.link2room.soundwave.constant.SoundwaveMnsConstant;
import com.link2room.soundwave.constant.SoundwaveTaskNameConstant;
import com.link2room.soundwave.dto.param.inside.PmsRoomAvailInsideParamDto;
import com.link2room.soundwave.dto.result.base.PmsRmtypeAvailDto;
import com.link2room.soundwave.service.IYhPmsBaseService;
import org.springframework.stereotype.Component;
import yuheng.pms.result.YhRmtypeAvailDto;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by sss on 2017/5/18.
 */
@Component("yhPmsRoomAvailHandlerFacadeService")
public class YhPmsRoomAvailHandlerFacadeServiceImpl extends AbstractPmsRoomAvailHandlerFacadeServiceImpl {
    @Resource
    private ICommonService commonService;
    @Resource
    private IYhPmsBaseService yhPmsBaseService;

    @Override
    void syncPMSRoomAvail(PmsRoomAvailInsideParamDto pmsRoomAvailInsideParamDto) throws Exception {
        L2RYhHotel queryIH = new L2RYhHotel();
        queryIH.setLhotelGroupCode(pmsRoomAvailInsideParamDto.getLhotelGroupCode());
        queryIH.setIsHalt(DefaultValue.F);
        if(StringUtil.isNotBlank( pmsRoomAvailInsideParamDto.getLhotelCode() )){
            queryIH.setLhotelCode( pmsRoomAvailInsideParamDto.getLhotelCode());
        }
        Date now = new Date();

        QueryResult<L2RYhHotel> l2RPmsHotelQueryResult= commonService.findAllEQ( L2RYhHotel.class, queryIH);
        if(  null !=l2RPmsHotelQueryResult.getResultlist()&& l2RPmsHotelQueryResult.getResultlist().size()>0){
            Date arr= DateUtil.addDays( now, pmsRoomAvailInsideParamDto.getStartIndex() );
            Date dep=DateUtil.addDays( arr, pmsRoomAvailInsideParamDto.getDayStep());
            String arrtime=DateUtil.getWebDateString(arr);
            String deptime=DateUtil.getWebDateString(dep);
            List<PmsRoomAvailInsideParamDto> pmsRoomAvailParamDtos=new ArrayList<>();
            if(l2RPmsHotelQueryResult.getResultlist()!=null&&l2RPmsHotelQueryResult.getResultlist().size()>0){
                for (L2RYhHotel l2RYhHotel1 : l2RPmsHotelQueryResult.getResultlist()) {
                    PmsRoomAvailInsideParamDto pmsRoomAvailParamDto = new PmsRoomAvailInsideParamDto();
                    pmsRoomAvailParamDto.setPmsHotelCode( l2RYhHotel1.getHotelCode() );
                    pmsRoomAvailParamDto.setPmsHotelGroupCode( l2RYhHotel1.getGroupCode());
                    pmsRoomAvailParamDto.setArrtime(arrtime);
                    pmsRoomAvailParamDto.setDeptime(deptime);
                    pmsRoomAvailParamDto.setRmtypes("");
                    pmsRoomAvailParamDto.setLhotelGroupCode(l2RYhHotel1.getLhotelGroupCode() );
                    pmsRoomAvailParamDto.setLhotelCode(l2RYhHotel1.getLhotelCode() );
                    if(null==l2RYhHotel1.getUnuseRmnum()){
                        pmsRoomAvailParamDto.setUnuseRmnum(0);
                    }else {
                        pmsRoomAvailParamDto.setUnuseRmnum(l2RYhHotel1.getUnuseRmnum());
                    }
                    pmsRoomAvailParamDtos.add(pmsRoomAvailParamDto);
                }
                BatchUtil.beginBatchTaskInterval(SoundwaveMnsConstant.QUEUE_PMSROOMAVAIL,
                        SoundwaveTaskNameConstant.SAVE_PMS_ROOMAVAIL,
                        pmsRoomAvailParamDtos,10);
            }
        }
    }

    @Override
    void syncPMSHotelRoomAvail(PmsRoomAvailInsideParamDto pmsRoomAvailInsideParamDto) throws Exception {
        String lhotelGroupCode=pmsRoomAvailInsideParamDto.getLhotelGroupCode();
        String lhotelCode=pmsRoomAvailInsideParamDto.getLhotelCode();
        L2RAssert.stringBlank(lhotelCode,"酒店代码为空");
        L2RYhHotel l2RYhHotel = new L2RYhHotel();
        l2RYhHotel.setLhotelCode(lhotelCode );
        l2RYhHotel.setLhotelGroupCode(lhotelGroupCode);
        l2RYhHotel= commonService.findOneEQ(L2RYhHotel.class,l2RYhHotel );
        if(l2RYhHotel!=null) {
            L2RYhRmtype queryLYR=new L2RYhRmtype();
            queryLYR.setLhotelGroupCode(lhotelGroupCode);
            queryLYR.setLhotelCode(lhotelCode);
            QueryResult<L2RYhRmtype> l2RYhRmtypeQueryResult = commonService.findAllEQ(L2RYhRmtype.class, queryLYR);
            List<L2RYhRmtype> l2RYhRmtypeList = l2RYhRmtypeQueryResult.getResultlist();
            if(l2RYhRmtypeList!=null){
                List<YhRmtypeAvailDto> yhRmtypeAvailDtos = yhPmsBaseService.getYhRoomStockList(lhotelGroupCode,
                        l2RYhHotel.getGroupCode(),
                        l2RYhHotel.getHotelCode(),
                        null,
                        pmsRoomAvailInsideParamDto.getArrtime(),
                        pmsRoomAvailInsideParamDto.getDeptime() );
                List<YhRmtypeAvailSync> yhRmtypeAvailSyncs=new ArrayList<>();
                if(yhRmtypeAvailDtos!=null){
                    YhRmtypeAvailSync yhRmtypeAvailSync;
                    for(YhRmtypeAvailDto yhRmtypeAvailDto:yhRmtypeAvailDtos){
                        yhRmtypeAvailSync=new YhRmtypeAvailSync();
                        yhRmtypeAvailSync.setAvail(yhRmtypeAvailDto.getCurrentQuantity());
                        yhRmtypeAvailSync.setBusinessDate(yhRmtypeAvailDto.getBusinessDate());
                        yhRmtypeAvailSync.setRmtype(yhRmtypeAvailDto.getRoomType());
                        yhRmtypeAvailSyncs.add(yhRmtypeAvailSync);
                    }
                }
                L2RCondition l2RCondition = new L2RCondition();
                l2RCondition.setAndConditions(new ConditionDetail[]{
                        new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, lhotelGroupCode),
                        new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ, lhotelCode),
                        new ConditionDetail(YhRmtypeAvailSync.YhRmtypeAvailSync_.businessDate.toString(), CriteriaUtil.Operator.GTE, DateUtil.parseDateNewFormat(pmsRoomAvailInsideParamDto.getArrtime())),
                        new ConditionDetail(YhRmtypeAvailSync.YhRmtypeAvailSync_.businessDate.toString(), CriteriaUtil.Operator.LTE, DateUtil.parseDateNewFormat(pmsRoomAvailInsideParamDto.getDeptime()))
                });
                QueryResult<YhRmtypeAvailSync> pmsRmtypeAvailSyncResult = commonService.findAllByCondition(YhRmtypeAvailSync.class, l2RCondition);
                Iterator<YhRmtypeAvailSync> it = yhRmtypeAvailSyncs.iterator();
                List<YhRmtypeAvailSync> truePmsRmtypeAvailList=new ArrayList<>();
                while (it.hasNext()){
                    YhRmtypeAvailSync yhRmtypeAvailSync = it.next();
                    for(L2RYhRmtype yhRmtype:l2RYhRmtypeList){
                        if(yhRmtypeAvailSync.getRmtype().equals(yhRmtype.getPmsRmtype())){
                            truePmsRmtypeAvailList.add(yhRmtypeAvailSync);
                        }
                    }
                }
                List<YhRmtypeAvailSync> oldPmsRmtypeAvailList = pmsRmtypeAvailSyncResult.getResultlist();
                Iterator<YhRmtypeAvailSync> trueIt = truePmsRmtypeAvailList.iterator();
                while (trueIt.hasNext()) {
                    YhRmtypeAvailSync yhRmtypeAvailSync = trueIt.next();
                    yhRmtypeAvailSync.setLhotelGroupCode(lhotelGroupCode);
                    yhRmtypeAvailSync.setLhotelCode(lhotelCode);
                    Integer saleNum= yhRmtypeAvailSync.getAvail()-pmsRoomAvailInsideParamDto.getUnuseRmnum();
                    if(saleNum<0){
                        saleNum=0;
                    }
                    yhRmtypeAvailSync.setSaleNum(saleNum);
                    yhRmtypeAvailSync.setL2RRmtype(lhotelCode+ DefaultValue.MARK + yhRmtypeAvailSync.getRmtype());

                    if (oldPmsRmtypeAvailList != null && oldPmsRmtypeAvailList.size() > 0) {
                        for (YhRmtypeAvailSync oldPmsRmtypeAvail : oldPmsRmtypeAvailList) {
                            if (oldPmsRmtypeAvail.getRmtype().equals(yhRmtypeAvailSync.getRmtype())
                                    && DateUtil.format(oldPmsRmtypeAvail.getBusinessDate(), DateUtil.webFormat).equals(DateUtil.format(yhRmtypeAvailSync.getBusinessDate(), DateUtil.webFormat))) {
                                oldPmsRmtypeAvail.setSaleNum(yhRmtypeAvailSync.getSaleNum());
                                oldPmsRmtypeAvail.setAvail(yhRmtypeAvailSync.getAvail());
                                trueIt.remove();
                                break;
                            }
                        }
                    }
                }
                commonService.mergeList(oldPmsRmtypeAvailList);
                commonService.saveList(truePmsRmtypeAvailList);
                BatchUtil.doBatchTaskDone(pmsRoomAvailInsideParamDto.getTaskMainId(),
                        pmsRoomAvailInsideParamDto.getTaskId(),
                        pmsRoomAvailInsideParamDto.getIsBatch());
            }else {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_MAPPINGRMTYPE_NOT_EXIT);
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_MAPPINGHOTEL_NOT_EXIT);
        }

    }

    @Override
    List<PmsRmtypeAvailDto> getPmsRoomAvailDirect(PmsRoomAvailInsideParamDto roomAvailInsideParamDto) throws Exception {

        L2RYhHotel l2RYhHotel = new L2RYhHotel();
        l2RYhHotel.setLhotelGroupCode(roomAvailInsideParamDto.getLhotelGroupCode());
        L2RAssert.stringBlank(roomAvailInsideParamDto.getLhotelCode(),"酒店代码为空");
        l2RYhHotel.setLhotelCode( roomAvailInsideParamDto.getLhotelCode());

        l2RYhHotel  = commonService.findOneEQ( L2RYhHotel.class, l2RYhHotel);
        Optional.ofNullable(l2RYhHotel).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_MAPPINGHOTEL_NOT_EXIT));
        L2RYhRmtype querylrmtype = new L2RYhRmtype();
        querylrmtype.setLhotelGroupCode(roomAvailInsideParamDto.getLhotelGroupCode());
        querylrmtype.setLhotelCode( roomAvailInsideParamDto.getLhotelCode());
        querylrmtype.setL2RRmtype(roomAvailInsideParamDto.getL2RRmtypes());
        L2RYhRmtype l2RYhRmtype = commonService.findOneEQ( L2RYhRmtype.class,querylrmtype );
        Optional.ofNullable(l2RYhRmtype).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_MAPPINGRMTYPE_NOT_EXIT));
        List<YhRmtypeAvailDto> yhRmtypeAvailDtos = yhPmsBaseService.getYhRoomStockListDirect(l2RYhHotel.getLhotelGroupCode(),
                l2RYhHotel.getGroupCode(),
                l2RYhHotel.getHotelCode(),
                l2RYhRmtype.getPmsRmtype(),
                DateUtil.getWebDateString(roomAvailInsideParamDto.getArr()),
                DateUtil.getWebDateString(roomAvailInsideParamDto.getDep())
                );
        List<PmsRmtypeAvailDto> rmtypeAvailDirects=new ArrayList<>();
        PmsRmtypeAvailDto pmsRmtypeAvailDto;
        for(YhRmtypeAvailDto yhRmtypeAvailDto:yhRmtypeAvailDtos){
            if(l2RYhRmtype.getPmsRmtype().equals(yhRmtypeAvailDto.getRoomType())){
                pmsRmtypeAvailDto=new PmsRmtypeAvailDto();
                pmsRmtypeAvailDto.setRsvDate(yhRmtypeAvailDto.getBusinessDate());
                pmsRmtypeAvailDto.setAvail(yhRmtypeAvailDto.getCurrentQuantity());
                pmsRmtypeAvailDto.setL2RRmtype(l2RYhRmtype.getL2RRmtype());
                pmsRmtypeAvailDto.setRmtype(l2RYhRmtype.getPmsRmtype());
                Integer saleNum=yhRmtypeAvailDto.getCurrentQuantity()-l2RYhHotel.getUnuseRmnum();
                if(saleNum<0){
                    saleNum=0;
                }
                pmsRmtypeAvailDto.setSaleNum(saleNum);
                rmtypeAvailDirects.add(pmsRmtypeAvailDto);
            }
        }
        return rmtypeAvailDirects;
    }

    @Override
    void deletePmsRoomAvail(BaseL2rParamDto baseL2rParamDto) throws Exception {
        L2RCondition l2RCondition=new L2RCondition();
        l2RCondition.setAndConditions(
                new ConditionDetail[]{
                        new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, baseL2rParamDto.getLhotelGroupCode()),
                        new ConditionDetail(YhRmtypeAvailSync.YhRmtypeAvailSync_.businessDate.toString(), CriteriaUtil.Operator.LT, DateUtil.addDays(new Date(),-baseL2rParamDto.getDayStep()))
                }
        );
        commonService.deleteByCondition(YhRmtypeAvailSync.class,l2RCondition);
    }

    @Override
    QueryResult<PmsRmtypeAvailDto> getPmsRoomAvail(PmsRoomAvailInsideParamDto roomAvailInsideParamDto) throws Exception {
        List<String> l2rRmtypes = new ArrayList<>();
        if( roomAvailInsideParamDto.getL2RRmtypes()!=null&& roomAvailInsideParamDto.getL2RRmtypes().length()>0){
            String [] temp= roomAvailInsideParamDto.getL2RRmtypes().split(",");
            for ( String str : temp){
                l2rRmtypes.add( str);
            }
        }
        L2RCondition stockConfition=new L2RCondition();
        stockConfition.setAndConditions(new ConditionDetail[]{
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, roomAvailInsideParamDto.getLhotelGroupCode()),
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ, roomAvailInsideParamDto.getLhotelCode()),
                new ConditionDetail(BaseEntity.BaseEntity_.isHalt.toString(), CriteriaUtil.Operator.EQ,"F"),
                new ConditionDetail(YhRmtypeAvailSync.YhRmtypeAvailSync_.businessDate.toString(), CriteriaUtil.Operator.GTE, DateUtil.parseDateWevFormat(roomAvailInsideParamDto.getArrtime())),
                new ConditionDetail(YhRmtypeAvailSync.YhRmtypeAvailSync_.businessDate.toString(), CriteriaUtil.Operator.LT, DateUtil.parseDateWevFormat(roomAvailInsideParamDto.getDeptime())),
                new ConditionDetail(YhRmtypeAvailSync.YhRmtypeAvailSync_.l2RRmtype.toString(), CriteriaUtil.Operator.IN,l2rRmtypes)

        });
        QueryResult<YhRmtypeAvailSync> rmtypeAvailkResult = commonService.findAllByCondition(YhRmtypeAvailSync.class, stockConfition);
        QueryResult<PmsRmtypeAvailDto> pmsRmtypeAvailDtoQueryResult=new QueryResult<>();
        pmsRmtypeAvailDtoQueryResult.setCurrentPage(rmtypeAvailkResult.getCurrentPage());
        pmsRmtypeAvailDtoQueryResult.setTotalrecord(rmtypeAvailkResult.getTotalrecord());
        if(rmtypeAvailkResult.getResultlist()!=null){
            List<PmsRmtypeAvailDto> pmsRmtypeAvailDtos=new ArrayList<>();
            PmsRmtypeAvailDto pmsRmtypeAvailDto;
            for(YhRmtypeAvailSync yhRmtypeAvailSync:rmtypeAvailkResult.getResultlist()){
                pmsRmtypeAvailDto=ClassConverUtil.copyPropertiesToDto(yhRmtypeAvailSync,PmsRmtypeAvailDto.class,false);
                pmsRmtypeAvailDto.setRsvDate(yhRmtypeAvailSync.getBusinessDate());
                pmsRmtypeAvailDto.datetimeToString();
                pmsRmtypeAvailDtos.add(pmsRmtypeAvailDto);
            }
            pmsRmtypeAvailDtoQueryResult.setResultlist(pmsRmtypeAvailDtos);
        }
        return pmsRmtypeAvailDtoQueryResult;
    }
}
